﻿using Newtonsoft.Json;
using NLog.Fluent;
using SHDM.Cache;
using SHDM.Web.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Filters;
using System.Web.Http.Results;

namespace SHDM.Web.Infrastructure
{
    public class AuthenticatorAttribute : Attribute, IAuthenticationFilter, IFilter
    {
        public bool AllowMultiple
        {
            get
            {
                return false;
            }
        }

        public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
        {
            var req = context.Request;
            try
            {
                if (req.Headers.Authorization != null &&
                    req.Headers.Authorization.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase))
                {
                    string token = req.Headers.Authorization.Parameter;                   
                    var accountInfo = Cacher.Instance.Get<AccountInfo>($"{Cacher.KeySpace.UserToken}.{token}");
                    if (accountInfo == null || accountInfo.ID <= 0)
                    {
                        context.ErrorResult = new UnauthorizedResult(
                             new AuthenticationHeaderValue[0],
                             context.Request);
                    }
                    else
                    {
                        context.Principal = new HPrincipal(new HIdentity(accountInfo));
                    }
                }
                else
                {
                    context.ErrorResult = new UnauthorizedResult(
                             new AuthenticationHeaderValue[0],
                                                  context.Request);
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex.ToString());
                context.ErrorResult = new ExceptionResult(ex);
            }

            return Task.FromResult(0);
        }

        public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
        {
            context.Result = new ResultWithChallenge(context.Result);
            return Task.FromResult(0);
        }

        public class ResultWithChallenge : IHttpActionResult
        {
            private readonly IHttpActionResult next;
            public ResultWithChallenge(IHttpActionResult next)
            {
                this.next = next;
            }
            public async Task<HttpResponseMessage> ExecuteAsync(
              CancellationToken cancellationToken)
            {

                var response = await next.ExecuteAsync(cancellationToken);
                if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    var result = new Result() { ErrorCode = -1, ErrorMessage = "身份认证失败,请重新登录" };
                    response.Content = new StringContent(JsonConvert.SerializeObject(result), Encoding.UTF8, "application/json");
                }
                return response;
            }
        }
    }
}